#include <QDir>
#include "../../datamanager/geometrydatanode.h"
#include "volumerendercontrol.h"
#include "volumerenderer.h"

using namespace PBVP;

VolumeRenderControl::VolumeRenderControl(VolumeRenderer *pRenderer, QWidget *parent)
: QWidget(parent)
{
	ui.setupUi(this);
	m_pVolRenderer = pRenderer;
	m_MapSize = 256;
	m_pColorTable = ui.colorTable;
	m_pContour = NULL;

	updateColorMap();

	loadMapFiles();

	connect(m_pColorTable, SIGNAL(functionChanged()), this, SLOT(updateColorMap()));
	connect(m_pColorTable, SIGNAL(everythingChanged()), this, SLOT(updateColorMap()));
	connect(m_pColorTable, SIGNAL(isocontourNodeAdded(int, double, double, double, double)),
			this, SLOT(addIsoContour(int, double, double, double, double)));
	connect(m_pColorTable, SIGNAL(isocontourNodeChanged(int, double, double, double, double)),
			this, SLOT(updateIsoContour(int, double, double, double, double)));
	connect(m_pColorTable, SIGNAL(isocontourNodeDeleted(int)), this, SLOT(deleteIsoContour(int)));
	
	connect(ui.qualitySlider, SIGNAL(sliderMoved(int)), m_pVolRenderer, SLOT(changeQuality(int)));
	connect(ui.volumeCheckBox, SIGNAL(stateChanged(int)), m_pVolRenderer, SLOT(setShowVolume(int)));
	connect(ui.bboxCheckBox, SIGNAL(stateChanged(int)), m_pVolRenderer, SLOT(setShowBBox(int)));
	connect(ui.mapFileList, SIGNAL(activated(int)), this, SLOT(loadColorMap(int)));
}

VolumeRenderControl::~VolumeRenderControl()
{

}

//////////////////////////////////////////////////////////////////////////
// Private functions
//////////////////////////////////////////////////////////////////////////
void VolumeRenderControl::getColorMapUC(unsigned char ucArray[], int size)
{
	double *cmapVals = new double[4*size];
	m_pColorTable->GetTransferFunction(cmapVals, size);
	for (int i = 0; i < 4*size; i++) {
		ucArray[i] = (unsigned char)(cmapVals[i] * 255);
	}
	delete[] cmapVals;
}

void VolumeRenderControl::loadMapFiles()
{
	QDir cmapDir;
	cmapDir.cd("colormaps");

	ui.mapFileList->clear();
	QStringList cMaps = cmapDir.entryList(QDir::Files);
	foreach (QString fname, cMaps)
	{
		if(fname.endsWith(".cmap")) 
		{
			QString path = cmapDir.absoluteFilePath(fname);
			ui.mapFileList->addItem(fname, path);
		}
	}
}

//////////////////////////////////////////////////////////////////////////
// slots
//////////////////////////////////////////////////////////////////////////
void VolumeRenderControl::updateColorMap()
{
	unsigned char *ucArray = new unsigned char[4*m_MapSize];
	getColorMapUC(ucArray, m_MapSize);
	m_pVolRenderer->loadColormapTexture(ucArray, m_MapSize);
	m_pVolRenderer->updateView();
	delete[] ucArray;
}

void VolumeRenderControl::addIsoContour(int index, double isovalue, double R, double G, double B)
{
	printf("Isocountour Node %d added at %f\n", index, isovalue);

	m_pContour = m_pVolRenderer->addContour(isovalue);
}

void VolumeRenderControl::updateIsoContour(int index, double isovalue, double R, double G, double B)
{
	printf("Updaet Isocontour Node to new isovalue %f\n", isovalue);
	m_pVolRenderer->updateContour(m_pContour, isovalue);
}

void VolumeRenderControl::deleteIsoContour(int index)
{
	printf("Delete Isocontour Node\n");
	m_pVolRenderer->deleteContour(m_pContour);
}

void VolumeRenderControl::loadColorMap(int index)
{
	QString fname = ui.mapFileList->itemData(index).toString();
	loadMapFiles();
	m_pColorTable->loadMap(fname);
}

void VolumeRenderControl::setMinMaxLabels(float fmin, float fmax)
{
	ui.minLabel->setText(QString().setNum(fmin));
	ui.maxLabel->setText(QString().setNum(fmax));
}